#ifndef __GARBAGE_OBJECT_H__
#define __GARBAGE_OBJECT_H__

#include "Def.h"
#include <memory>
#include <unordered_map>


class GarbageObject
{
    friend class GarbageManager;
public:
    GarbageObject();
    virtual ~GarbageObject();

    // 释放减少引用
	virtual void Release(GarbageObject* target = nullptr);
	
    // 保留增加引用
	virtual void Retain(GarbageObject* target = nullptr);

public:

    /*
        重载new关键字
    */
    void* operator new(size_t size)
    {
        GarbageObject* obj = static_cast<GarbageObject*>(std::malloc(size));
        GarbageObject::OnNewObject(obj);
        return obj;
    }

    void *operator new(std::size_t count,  const std::nothrow_t&) throw()
    {
        GarbageObject* obj = static_cast<GarbageObject*>(std::malloc(count));
        GarbageObject::OnNewObject(obj);
        return obj;
    }

    void *operator new(std::size_t count, void *ptr) throw()
    {
        return ptr;
    }

    /*
        重载delete关键字
    */
    void operator delete(void* obj)
    {
        GarbageObject::OnDeleteObject(static_cast<GarbageObject*>(obj));
        std::free(obj);
    }

private:
    static void OnNewObject(GarbageObject* obj);            // 被new时调用
    static void OnDeleteObject(GarbageObject* obj);         // 被delete时调用
    bool CheckHasRef(GarbageObject* obj);                   // 检查是否有引用
    void DoMark();

private:
    bool isGarbage_ = false;                                // 是否是垃圾
    bool gcCheckMark_ = false;                              // gc检查标记
    std::unordered_map<GarbageObject*, int> refTable_;      // 引用表
};

#endif
